package com.lm.auth.controller;

import cn.hutool.json.JSONUtil;
import com.lm.common.result.Result;
import com.nimbusds.jose.jwk.JWKSet;
import com.nimbusds.jose.jwk.RSAKey;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.oauth2.common.OAuth2AccessToken;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.annotation.*;

import java.security.KeyPair;
import java.security.Principal;
import java.security.interfaces.RSAPublicKey;
import java.util.Map;

@Slf4j
@RestController
@RequestMapping("/oauth")
@AllArgsConstructor
public class AuthController {

    private TokenEndpoint tokenEndpoint;
    private RedisTemplate redisTemplate;
    private KeyPair keyPair;


    /*    @ApiOperation(value = "OAuth2认证", notes = "登录入口")
        @ApiImplicitParams({
                @ApiImplicitParam(name = "grant_type", defaultValue = "password", value = "授权模式", required = true),
                @ApiImplicitParam(name = "client_id", defaultValue = "client", value = "Oauth2客户端ID", required = true),
                @ApiImplicitParam(name = "client_secret", defaultValue = "123456", value = "Oauth2客户端秘钥", required = true),
                @ApiImplicitParam(name = "refresh_token", value = "刷新token"),
                @ApiImplicitParam(name = "username", defaultValue = "admin", value = "用户名"),
                @ApiImplicitParam(name = "password", defaultValue = "123456", value = "用户密码")
        })*/
    @PostMapping("/token")
    public Object postAccessToken(Principal principal, @RequestParam Map<String, String> parameters) throws HttpRequestMethodNotSupportedException {

        /**
         * 获取登录认证的客户端ID
         *
         * 兼容两种方式获取Oauth2客户端信息（client_id、client_secret）
         * 方式一：client_id、client_secret放在请求路径中(注：当前版本已废弃)
         * 方式二：放在请求头（Request Headers）中的Authorization字段，且经过加密，例如 Basic Y2xpZW50OnNlY3JldA== 明文等于 client:secret
         */
       /* String clientId = RequestUtils.getOAuth2ClientId();
        log.info("OAuth认证授权 客户端ID:{}，请求参数：{}", clientId, JSONUtil.toJsonStr(parameters));

        *//**
         * knife4j接口文档测试使用
         *
         * 请求头自动填充，token必须原生返回，不能有任何包装，否则显示 undefined undefined
         * 账号/密码:  client_id/client_secret : client/123456
         *//*
        if (SecurityConstants.TEST_CLIENT_ID.equals(clientId)) {
            return tokenEndpoint.postAccessToken(principal, parameters).getBody();
        }*/
        OAuth2AccessToken accessToken;
        try {
            accessToken = tokenEndpoint.postAccessToken(principal, parameters).getBody();
        } catch (Exception e) {
            return Result.success(e.getMessage());
        }


        return Result.success(accessToken);
    }


    @GetMapping("/rsa/publicKey")
    public Map<String, Object> getKey() {
        RSAPublicKey publicKey = (RSAPublicKey) keyPair.getPublic();
        RSAKey key = new RSAKey.Builder(publicKey).build();
        return new JWKSet(key).toJSONObject();
    }

    public static void main(String[] args) {
        String encode = new BCryptPasswordEncoder().encode("P@ssw0rd");
        System.out.println(encode);

        String encode2 = PasswordEncoderFactories.createDelegatingPasswordEncoder().encode("P@ssw0rd");
        System.out.println(encode2);
    }
}
